/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hps.model;

import java.awt.Graphics;
import java.awt.Image;
import java.util.ArrayList;
import javax.swing.ImageIcon;

/**
 *
 * @author $Author: NIKE3500 $
 * @version $Revision: 85 $
 * @date $Date: 2013-01-14 18:59:09 +0000 (Mon, 14 Jan 2013) $
 */
public class Wall implements IInfluence
{

    //statisch
    private static Image wallImage;
    //Member
    private Point startPoint, endPoint;
    private ArrayList<Point> wallPoints;
    private ArrayList<IInfluence> me;

    public Wall(Point p1, Point p2)
    {
        if ((p1.getX() != p2.getX()) && (p1.getY() != p2.getY()))
        {
            throw new IllegalArgumentException("Wand muss gerade sein");
        }
        wallPoints = new ArrayList<Point>();
        me = new ArrayList<IInfluence>();
        me.add(this);
        //BlockedFields einrichten
        //Ordnen der Punkte        
        startPoint = new Point();
        endPoint = new Point();
        if (p1.getX() < p2.getX())
        {
            startPoint.setX(p1.getX());
            endPoint.setX(p2.getX());
        } else
        {
            endPoint.setX(p1.getX());
            startPoint.setX(p2.getX());

        }
        if (p1.getY() < p2.getY())
        {
            startPoint.setY(p1.getY());
            endPoint.setY(p2.getY());
        } else
        {
            endPoint.setY(p1.getY());
            startPoint.setY(p2.getY());
        }
        for (int i = startPoint.getX(); i <= endPoint.getX(); i++)
        {
            for (int j = startPoint.getY(); j <= endPoint.getY(); j++)
            {
                wallPoints.add(new Point(i, j));
            }
        }
    }

    @Override
    public void setInfluence(FloorField field)
    {
        byte[][] byteField = field.getField();
        for (Point p : wallPoints)
        {
            for (Point q : calcInfluenceArea(p))
            {
                if ((q.getX() >= 0)
                        && (q.getY() >= 0)
                        && (q.getX() < byteField.length)
                        && (q.getY() < byteField[0].length))
                {
                    byteField[q.getX()][q.getY()] -= byteField[q.getX()][q.getY()] < Byte.MIN_VALUE + 10 ? Byte.MIN_VALUE - byteField[p.getX()][p.getY()] : 10;
                }
            }
        }
    }

    /**
     * Waende verursachen keinen Schaden.
     * @param pedestrians 
     */
    @Override
    public void damage(ArrayList<Pedestrian> pedestrians) {
        //Waende verursachen keinen Schaden
    }

    /**
     * Liefert Punkte ueber und neben dem uebergebenen Punkt zurueck
     *
     * @param p Punkt, um den Punkte verteilt werden sollen
     * @return Point[4] mit den Punkten
     */
    private Point[] calcInfluenceArea(Point p)
    {
        Point[] rtrn = new Point[4];
        rtrn[0] = new Point(p.getX() - 1, p.getY());
        rtrn[1] = new Point(p.getX() + 1, p.getY());
        rtrn[2] = new Point(p.getX(), p.getY() - 1);
        rtrn[3] = new Point(p.getX(), p.getY() + 1);
        return rtrn;
    }

    @Override
    public ArrayList<IInfluence> spread(IInfluence[][] blocked)
    {
        return me;
    }

    @Override
    public int getBlocked(Point p)
    {
        return wallPoints.contains(p) ? 1 : 0;
    }

    @Override
    public ArrayList<Point> getBlockedFields()
    {
        return (ArrayList<Point>) wallPoints.clone();
    }

    @Override
    public boolean isBlocking()
    {
        return true;
    }

    @Override
    public boolean isAt(Point pos)
    {
        return this.wallPoints.contains(pos);
    }

    @Override
    public IInfluence clone()
    {
        return new Wall(startPoint, endPoint);
    }

    @Override
    public void draw(Graphics g, Point roomPosition, int singleFieldSize)
    {
        if (wallImage == null)
        {
            wallImage = new ImageIcon(getClass().getResource("/hps/view/HPS_icons/wand.png")).getImage();
        }
        for (Point p : wallPoints)
        {
            g.drawImage(wallImage,
                    roomPosition.getX() + p.getX() * singleFieldSize + 1,
                    roomPosition.getY() + p.getY() * singleFieldSize + 1,
                    singleFieldSize, singleFieldSize, null);
        }
    }
    
    /**
     * Equals-Methode fuer Mauern
     * @param o
     * @return 
     */
    @Override
    public boolean equals(Object o)
    {
        if (o == null)
        {
            return false;
        }
        if (!(o instanceof Wall))
        {
            return false;
        }
        if (!(o.hashCode() == this.hashCode()))
        {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode()
    {
        int hash = 3;
        hash = 83 * hash + (this.wallPoints != null ? this.wallPoints.hashCode() : 0);
        return hash;
    }
}
